Skip to content

Extract secret validation to lib.sh.#22

Open
AuraMindNest wants to merge 6 commits into
cppalliance:masterfrom
AuraMindNest:fix/secret-validation
Open

Extract secret validation to lib.sh.#22
AuraMindNest wants to merge 6 commits into
cppalliance:masterfrom
AuraMindNest:fix/secret-validation

Conversation

@AuraMindNest

@AuraMindNest AuraMindNest commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Close #20.

Summary by CodeRabbit

Release Notes

  • Chores

    • Improved CI/CD reliability by centralizing required environment and secret validation ahead of translation and submodule operations.
    • Added consistent, fail-fast validation for language code configuration, with clearer error behavior.
    • In Weblate mode, Weblate-specific secret checks run earlier and are no longer duplicated across steps.
    • Updated lint tooling to use pinned ShellCheck/Actionlint versions with caching for more predictable CI runs.
  • Tests

    • Expanded automated coverage for secret and language-code validation behaviors (including Weblate mode).

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@AuraMindNest, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 48 minutes and 51 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aab55b4e-2268-4364-8820-0115aa1b2767

📥 Commits

Reviewing files that changed from the base of the PR and between ff83593 and e07aa0f.

📒 Files selected for processing (2)
  • .github/workflows/start-translation.yml
  • scripts/lint.sh
📝 Walkthrough

Walkthrough

Inline secret and language-code validation checks in add-submodules.yml and start-translation.yml are removed and replaced by three new shared functions (require_lang_codes, _require_nonempty, validate_secrets) added to .github/workflows/assets/lib.sh. Both workflows are updated to source lib.sh early and call these helpers at the appropriate points. Separately, scripts/lint.sh is refactored to pin ShellCheck and Actionlint versions and cache the binaries under .cache/, replacing dynamic downloads with deterministic versioned tools.

Changes

Centralized Secret Validation

Layer / File(s) Summary
New validation functions in lib.sh
.github/workflows/assets/lib.sh
Adds header comments documenting the env.shlib.sh sourcing order. Implements require_lang_codes (fails fast if LANG_CODES is unset), _require_nonempty (generic named-variable non-empty check via indirect expansion), and validate_secrets (validates GITHUB_TOKEN, ORG, MODULE_ORG, BOT_NAME, BOT_EMAIL, BOOST_ORG, MASTER_BRANCH, TRANSLATIONS_REPO; when called with weblate, also requires WEBLATE_URL and WEBLATE_TOKEN).
add-submodules.yml: validation refactor
.github/workflows/add-submodules.yml
Sources lib.sh and calls require_lang_codes in "Validate language codes" step. Centralizes initialization by sourcing env.sh/lib.sh and calling validate_secrets in "Add submodules" step. Removes prior inline GITHUB_TOKEN and LANG_CODES guards and eliminates duplicate sourcing of helper scripts.
start-translation.yml: validation refactor
.github/workflows/start-translation.yml
Sources lib.sh and calls require_lang_codes in "Validate language codes" step. Moves sourcing of env.sh/lib.sh/translation.sh earlier and calls validate_secrets weblate before translation helpers. Removes later duplicate sourcing and inline secret checks. Renames trigger_weblate parameters from weblate_url/weblate_token to api_base_url/api_token and updates curl headers and URL construction.
Test coverage for validation functions
tests/test_lib.bats
Adds Bats tests covering require_lang_codes success and failure cases; validates validate_secrets against missing GITHUB_TOKEN and LANG_CODES; tests validate_secrets weblate for both success with all Weblate env vars and failure when WEBLATE_URL is unset.

Pinned Tool Versions for Linting

Layer / File(s) Summary
ShellCheck pinning and caching
scripts/lint.sh
Pins SHELLCHECK_VERSION at script top, establishes repo root and cache directories, creates ensure_shellcheck helper that downloads/verifies/extracts the pinned version to cache and creates a versioned bin symlink. Updates error messages to be explicit about unsupported-OS cases and gates extraction on versioned extract_dir presence.
Actionlint pinning and caching
scripts/lint.sh
Pins ACTIONLINT_VERSION at script top; creates ensure_actionlint helper that mirrors ShellCheck approach: computes tarball names from pinned version, downloads/checksums/extracts to versioned cache, copies binary to versioned bin path, and handles unsupported-OS cases. Updates main script flow to call both ensure-functions, prepend pinned ShellCheck directory to PATH, print versions from pinned binaries, and run linters over target globs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • cppalliance/boost-docs-translation#3: Modifies language-code validation and submodule targeting in workflows, aligning with the validation extraction and parameter standardization in this PR.

Suggested reviewers

  • henry0816191
  • wpak-ai

Poem

🐇 Hoppity hop, the checks are now neat,
No more repeated guards to repeat!
lib.sh holds the secrets with care,
Pinned tools hop fast with versions fair.
The rabbit approves: clean, tidy, complete! 🌿

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The rename of trigger_weblate parameters from weblate_url/weblate_token to api_base_url/api_token is functionally correct but unrelated to the stated goal of extracting validation logic. Move the trigger_weblate parameter rename to a separate PR or document it explicitly as an unrelated refactoring to reduce diff noise and improve clarity of the extraction changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective of the PR—extracting secret validation logic to lib.sh—which aligns with the changes across all modified workflow files.
Linked Issues check ✅ Passed All acceptance criteria from issue #20 are met: validation functions live in lib.sh with clear error messages, both workflows call the extracted functions in correct order, inline checks are removed, and optional weblate argument is implemented.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@AuraMindNest

Copy link
Copy Markdown
Collaborator Author

@coderabbitai, full review.

@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Get PR details and diff
gh pr view 22 --repo cppalliance/boost-docs-translation --json title,body,files,additions,deletions

echo "===== DIFF ====="
gh pr diff 22 --repo cppalliance/boost-docs-translation

Length of output: 8793


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Get the PR branch files
gh api repos/cppalliance/boost-docs-translation/contents/.github/workflows/assets/lib.sh \
  --jq '.content' | base64 -d

echo "===== add-submodules.yml ====="
gh api repos/cppalliance/boost-docs-translation/contents/.github/workflows/add-submodules.yml \
  -H "Accept: application/vnd.github.raw" 2>/dev/null || \
gh api repos/cppalliance/boost-docs-translation/git/trees/HEAD --jq '.tree[] | select(.path | contains("add-submodules"))' 2>/dev/null || true

echo "===== start-translation.yml ====="
gh api repos/cppalliance/boost-docs-translation/contents/.github/workflows/start-translation.yml \
  -H "Accept: application/vnd.github.raw" 2>/dev/null || true

Length of output: 30736



@AuraMindNest, here is the full review of PR #22.


Review: Extract secret validation to lib.sh

Overall: The centralization is well-structured. The three new helpers (require_lang_codes, _require_nonempty, validate_secrets) follow a clean hierarchy. Below are the issues I found, ordered by severity.


🔴 Medium — Fail-fast regression in start-translation.yml

In the old code, GITHUB_TOKEN, LANG_CODES, WEBLATE_URL, and WEBLATE_TOKEN were all validated at the top of the "Start translation" step before any sourcing. After this PR, validate_secrets weblate is called after sourcing three library files:

source "$GITHUB_WORKSPACE/.github/workflows/assets/env.sh"
source "$GITHUB_WORKSPACE/.github/workflows/assets/lib.sh"
source "$GITHUB_WORKSPACE/.github/workflows/assets/translation.sh"
validate_secrets weblate    # ← validation deferred to here

If translation.sh ever reads WEBLATE_URL or WEBLATE_TOKEN at source time (e.g., for initialisation), it would fail with a confusing error before the clear validation message fires. Consider moving validate_secrets weblate immediately before sourcing translation.sh (but after env.sh/lib.sh, since those provide ORG, MODULE_ORG, etc. that validate_secrets checks):

source "$GITHUB_WORKSPACE/.github/workflows/assets/env.sh"
source "$GITHUB_WORKSPACE/.github/workflows/assets/lib.sh"
validate_secrets weblate    # ← move here, before translation.sh
source "$GITHUB_WORKSPACE/.github/workflows/assets/translation.sh"

This matches the intent of the header comment: "Call validate_secrets … after sourcing env.sh and lib.sh."


🟡 Minor — Unrelated rename of trigger_weblate parameters

The diff includes a rename of two local parameters inside trigger_weblate():

-  local weblate_url="$1" weblate_token="$2" libs_ref="$3" exts_json="$4"
+  local api_base_url="$1" api_token="$2" libs_ref="$3" exts_json="$4"

This is functionally correct (positional call-site is unchanged) but is unrelated to the PR's stated goal of extracting validation. It adds noise to the diff and may confuse reviewers. Consider splitting it into a separate commit or noting it in the PR description.


🟡 Minor — _require_nonempty: SC2154 disable scope

_require_nonempty() {
  local var_name="$1" err_msg="$2"
  # shellcheck disable=SC2154
  [[ -n "${!var_name:-}" ]] || { echo "$err_msg" >&2; exit 1; }
}

The placement of # shellcheck disable=SC2154 is correct (it suppresses the next line). However, SC2154 is about a specific undeclared variable — shellcheck may not actually fire it here because var_name is explicitly declared as local. The real suppression needed might be SC2034 (variable appears unused) or none at all. Worth verifying with shellcheck -x locally to confirm the exact code being suppressed.


🟢 Nit — ${!var_name:-} — redundant :-

[[ -n "${!var_name:-}" ]]

Since var_name is a declared local parameter (always bound), ${!var_name:-} is equivalent to ${!var_name} here. The :- default is harmless and adds set -u safety, but could be documented with a brief comment to explain intent.


✅ What looks good

  • require_lang_codes cleanly extracts the duplicated pattern with the exact same error message as before, so existing tooling/log parsers are unaffected.
  • validate_secrets [weblate] flag design is clean — single optional argument gates the Weblate block without duplicating the base checks.
  • Header comments in lib.sh now document the expected sourcing order, which is valuable for future maintainers.
  • add-submodules.yml ordering is correct: validate_secrets is called after env.sh+lib.sh are sourced, ensuring all variables are available for validation.
  • The PR fully closes issue #20 — all inline validation blocks in both workflow files are removed.

Comment thread .github/workflows/add-submodules.yml Outdated
@henry0816191

Copy link
Copy Markdown

Add a few bats cases in tests/test_lib.bats for .github/workflows/assets/lib.shrequire_lang_codes & validate_secrets using load_env and unset/export patterns.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
tests/test_lib.bats (2)

163-187: ⚡ Quick win

Consider adding a test to verify the optional weblate parameter gates correctly.

The current tests verify that validate_secrets requires GITHUB_TOKEN and LANG_CODES, but there's no test confirming that validate_secrets (without the weblate argument) succeeds when WEBLATE_URL and WEBLATE_TOKEN are unset. This would prove the optional parameter correctly gates Weblate-specific checks.

🧪 Suggested additional test case
`@test` "validate_secrets: succeeds without Weblate secrets when weblate mode not requested" {
  load_env
  export GITHUB_TOKEN="test-token"
  export LANG_CODES="en"
  unset WEBLATE_URL
  unset WEBLATE_TOKEN
  run validate_secrets
  [ "$status" -eq 0 ]
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_lib.bats` around lines 163 - 187, The validate_secrets function
appears to have optional Weblate-related checks that are gated by a parameter,
but there is no test verifying that validate_secrets succeeds when called
without the weblate argument and Weblate environment variables are unset. Add a
new test case after the existing validate_secrets tests that calls
validate_secrets with required variables GITHUB_TOKEN and LANG_CODES set, but
with WEBLATE_URL and WEBLATE_TOKEN explicitly unset, and verify the function
returns a successful exit status of 0. This confirms that Weblate-specific
validation is properly gated by the optional parameter.

189-208: ⚡ Quick win

Consider adding a test for missing WEBLATE_TOKEN in weblate mode.

The test suite verifies that validate_secrets weblate fails when WEBLATE_URL is unset, but there's no corresponding test for when WEBLATE_TOKEN is unset. Adding this test would provide symmetric coverage of both Weblate-specific requirements.

🧪 Suggested additional test case
`@test` "validate_secrets weblate: fails when WEBLATE_TOKEN is unset" {
  load_env
  export GITHUB_TOKEN="test-token"
  export LANG_CODES="en"
  export WEBLATE_URL="https://weblate.example.org"
  unset WEBLATE_TOKEN
  run validate_secrets weblate
  [ "$status" -eq 1 ]
  [[ "$output" == *"WEBLATE_TOKEN secret is not set"* ]]
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_lib.bats` around lines 189 - 208, Add a new test case after the
"validate_secrets weblate: fails when WEBLATE_URL is unset" test that follows
the same pattern but tests for missing WEBLATE_TOKEN instead. The test should
load environment variables, set GITHUB_TOKEN, LANG_CODES, and WEBLATE_URL,
explicitly unset WEBLATE_TOKEN, run validate_secrets weblate, assert the status
is 1, and verify the output contains the message indicating WEBLATE_TOKEN secret
is not set. This provides symmetric test coverage for both required Weblate
configuration parameters.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/start-translation.yml:
- Around line 109-110: The comment on line 109 incorrectly attributes the
diagnostic code SC2153 to actionlint when it actually originates from
ShellCheck. Update the comment text to replace "actionlint SC2153" with
"ShellCheck SC2153" to correctly identify the source of the diagnostic warning
about potentially misspelled or unset variables.

In `@scripts/lint.sh`:
- Around line 160-162: The _shellcheck_dir variable is incorrectly set using
dirname on SHELLCHECK_BIN, which points to the cache directory instead of the
actual directory containing the shellcheck binary. Since the shellcheck binary
is extracted to shellcheck-v0.11.0/shellcheck, modify the _shellcheck_dir
assignment to point to the shellcheck-v0.11.0 subdirectory (the extract
directory) rather than using dirname on SHELLCHECK_BIN. This ensures that when
actionlint shells out to shellcheck, it will find the binary in the PATH.
- Around line 144-151: The extraction gate for actionlint uses an unversioned
path `$cache_dir/actionlint` to check whether extraction is needed, which causes
the old binary from a previous version to block extraction of a new version when
ACTIONLINT_VERSION is bumped. To fix this, create a versioned extraction
directory variable (similar to how Shellcheck handles it with extract_dir) that
incorporates ACTIONLINT_VERSION in the path, then update the conditional check
to use this versioned path instead of the unversioned `$cache_dir/actionlint`,
and update the tar extraction command to extract into the versioned directory to
ensure version upgrades trigger proper extraction and checksum verification.

---

Nitpick comments:
In `@tests/test_lib.bats`:
- Around line 163-187: The validate_secrets function appears to have optional
Weblate-related checks that are gated by a parameter, but there is no test
verifying that validate_secrets succeeds when called without the weblate
argument and Weblate environment variables are unset. Add a new test case after
the existing validate_secrets tests that calls validate_secrets with required
variables GITHUB_TOKEN and LANG_CODES set, but with WEBLATE_URL and
WEBLATE_TOKEN explicitly unset, and verify the function returns a successful
exit status of 0. This confirms that Weblate-specific validation is properly
gated by the optional parameter.
- Around line 189-208: Add a new test case after the "validate_secrets weblate:
fails when WEBLATE_URL is unset" test that follows the same pattern but tests
for missing WEBLATE_TOKEN instead. The test should load environment variables,
set GITHUB_TOKEN, LANG_CODES, and WEBLATE_URL, explicitly unset WEBLATE_TOKEN,
run validate_secrets weblate, assert the status is 1, and verify the output
contains the message indicating WEBLATE_TOKEN secret is not set. This provides
symmetric test coverage for both required Weblate configuration parameters.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d565c82d-ee93-4009-bde3-0ac3ef51706c

📥 Commits

Reviewing files that changed from the base of the PR and between 1f8130f and ff83593.

📒 Files selected for processing (5)
  • .github/workflows/add-submodules.yml
  • .github/workflows/assets/lib.sh
  • .github/workflows/start-translation.yml
  • scripts/lint.sh
  • tests/test_lib.bats
🚧 Files skipped from review as they are similar to previous changes (2)
  • .github/workflows/assets/lib.sh
  • .github/workflows/add-submodules.yml

Comment thread .github/workflows/start-translation.yml Outdated
Comment thread scripts/lint.sh Outdated
Comment thread scripts/lint.sh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extract secret validation to lib.sh

2 participants